<?php 
$g_xslDir = "xsl";

class FileManager
{
	static private $S_CONTENT_DIR		= '../content';
	
	//----------------------------------------------------------------------------------
	static public function normalizePath( $sPath )
	{
		if ( strpos( $sPath, '..' ) !== false )
			return '.';
		if ( $sPath == "" )
			return '.';
		$sPath = str_replace( '\\', '/', $sPath );
		$iLen = strlen( $sPath );
		while ( $sPath[ $iLen - 1 ] == '/' )
		{
			$sPath = substr( $sPath, 0, $iLen-1 );
			$iLen--;
		}
		return $sPath;
	}
		
	//----------------------------------------------------------------------------------
	static public function getContentPath( $sPath )
	{
		$sPath = FileManager::normalizePath( $sPath );
		$sPath = FileManager::$S_CONTENT_DIR.'/'.$sPath;
		return $sPath;
	}
	
	//----------------------------------------------------------------------------------
	static public function getRealPath( $sVirtualPath )
	{
		$sVirtualPath = FileManager::normalizePath( $sVirtualPath );
		$sParts = explode( ':', $sVirtualPath );
		if ( sizeof( $sParts ) != 2 )
		{
			echo 'bad virtual path : '.$sVirtualPath;
			return '';
		}
		$sDrive = $_SESSION[ $sParts[0] ];
		if ( !isset( $sDrive ) )
		{
			echo 'unknown drive in virtual path : '.$sVirtualPath;
			return '';
		}
		$sRealPath = '../'.$sDrive.$sParts[1];
		
		return $sRealPath;
	}
	
	//----------------------------------------------------------------------------------
	static private function getFileData( $file )
	{
		if( !file_exists( $file ) ) 
			return "";
			
		$iSize = filesize( $file );
		$in = fopen( $file, 'r' );
		$data = fread( $in, $iSize );
		fclose( $in );
		return $data;
	}
	
	//----------------------------------------------------------------------------------
	static public function getFileExtension( $sPath )
	{
		$sParts = explode( '.', $sPath );
		return $sParts[ sizeof( $sParts ) - 1 ];
	}
	
	//----------------------------------------------------------------------------------
	/** not tested */
	static public function getLongFileExtension( $sPath )
	{
		$sParts = explode( '/', $sPath );
		$sFileName = $sParts[ sizeof( $sParts ) - 1 ];
		$iDotPos = strpos( $sFileName, "." );
		$iSize = strlen( $sFileName );
		if ( $iDotPos+1 >= $iSize )
			return "";
		else
			return substr( $sFileName, $iDotPos+1 );
	}
	
	//----------------------------------------------------------------------------------
	/**
	 * Converts XML to HTML using some xslt file
	 * note :  the $oResponse is only used to send errors
	 *
	 * @param ServerResponse $oResponse
	 * @param String $sXmlPath
	 * @param String $sXslPath
	 * @param String $params
	 * @return String
	 */
	static public function xml2html( $oResponse, $sXmlPath, $sXslPath, $params = null) 
	{
		if( version_compare(PHP_VERSION,'5','>=') )
		{
			$xsl = new DomDocument();
			$xsl->load($sXslPath);
			$inputdom = new DomDocument();
			$inputdom->load($sXmlPath);
			
			$proc 	= new XsltProcessor();
			$xsl 	= $proc->importStylesheet($xsl);
			//$proc->setParameter(null, "argLang", "fr");
			
			$newdom = $proc->transformToDoc($inputdom);
			$html 	= $newdom->saveXML();
		}
		else
		{
			$xsltproc 	= xslt_create();
			xslt_set_encoding($xsltproc, 'utf-8');
			
			$args = array(
				 '/_xml' => FileManager::getFileData($sXmlPath),
				 '/_xsl' => FileManager::getFileData($sXslPath)
				);
			$html 		= xslt_process($xsltproc, "arg:/_xml", "arg:/_xsl", null, $args, $params);
		
			if ( empty( $html ) ) 
			{
				$oResponse->error( ' XSLT document transformation error : '. xslt_error($xsltproc) );
				return "";
			}
			xslt_free($xsltproc);
		}
	  return $html;
	}
	
	//----------------------------------------------------------------------------------
	/**
	 * @param ServerResponse $oResponse
	 * @param String $sFile
	 * @param String $sXslDir
	 */
	static public function readXmlContentFile( $oResponse, $sFile, $sXslDir = "xsl" )
	{
	  if ( !file_exists($sFile) ) 
	  { 
	  	$oResponse->error( "Cannot find the corresponding xml file : ".$sFile );
	  	return;
	  }
	  
	  // Find corresponding xsl file (using the filename convention)
	  $sTmpArray       = explode( ".", $sFile );
	  if ( sizeof( $sTmpArray ) < 3 )
	  {
	  	$oResponse->error( "The file extension of ".$sFile." doesn't follow the convention : DIR/DIR/NAME.TYPE.xml (e.g. content/test.char.xml)" );
	  	return;
	  }
	  $sFileType       = $sTmpArray[ sizeof( $sTmpArray ) - 2 ];
	  $sXslFileName    = $sXslDir."/html.".$sFileType.".xsl";
	  if( !file_exists( $sXslFileName ) )
	  {
	  	$oResponse->error( "Cannot find the corresponding xsl file : ".$sXslFileName );
	  	return;
	  }
	  
	  // transform data
	  $sTransformedData = FileManager::xml2html( $oResponse, $sFile, $sXslFileName );
	  
	  $oResponse->data( $sTransformedData );
	  
	  $oResponse->requestExecuted();
	  
	  return;
	}
	
	//----------------------------------------------------------------------------------
	static public function createContentFile( $oResponse, $sFilePath, $sTemplatePath = null )
	{
	  if ( file_exists( $sFilePath ) )
	  {
	  	$oResponse->error( "File already exists : ".$sFilePath );
	    return;
	  }
	  
	  if ( $sTemplatePath != null 
	  	&& file_exists( $sTemplatePath ) 
	  	&& is_file( $sTemplatePath )
	  	&& is_readable( $sTemplatePath ) )
	  {
	  	$bTemplateOk = true;
	  	if ( !file_exists( $sTemplatePath ) )
	  	{
	  		$oResponse->warning( 'Cannot find template file : '.$sTemplatePath );
	  		$bTemplateOk = false;
	  	}
	  	if ( !is_file( $sTemplatePath ) )
	  	{
	  		$oResponse->warning( 'The template "'.$sTemplatePath.'" is not a file');
	  		$bTemplateOk = false;
	  	}
	  	if ( !is_readable( $sTemplatePath ) )
	  	{
	  		$oResponse->warning( 'The template "'.$sTemplatePath.'" is not readable');
	  		$bTemplateOk = false;
	  	}
	  	
	  	if ( $bTemplateOk )
	  	{
	  		if ( !copy( $sTemplatePath, $sFilePath ) )
	  		{
	  			$oResponse->error( 'Cannot create file : "'.sFilePath.'"' );
	  			return;
	  		}
	  		
	  		$oResponse->data( getFileData( $sFilePath ) );
	  	}
	  }
	  else 
	  {
	 	$oFile = fopen( $sFilePath, 'wc' );
		if ( $oFile == null )
		{
			$oResponse->error( 'Cannot create file : "'.sFilePath.'"' );
			return;
		}
		fwrite( $oFile, '<pulse>\n</pulse>' );
		//$iSize = filesize( $sFilePath );
		//$oData = fread( $oFile, $iSize );
		fclose( $oFile );
		
		//$oResponse->data( $oData );
	  }
	  
	  $oResponse->requestExecuted();
	}
		
	//----------------------------------------------------------------------------------
	static public function createContentDir( $oResponse, $sDirPath )
	{
	  if ( file_exists( $sDirPath ) )
	  {
	  	$oResponse->error( 'Folder already exists : '.$sDirPath );
	    return;
	  }
	  
	 	if ( !mkdir( $sDirPath ) )
	 	{
	 		$oResponse->error( 'Cannot create folder : '.$sDirPath );
	 		return;
	 	}
	  
	  $oResponse->requestExecuted();
	}
		
	//----------------------------------------------------------------------------------
	static public function getFileOrDirName( $sPath )
	{
		$iPos = strrpos( $sPath, '/' );
		if ( $iPos === false )
			$iPos = strrpos( $sPath, '\\' );
		
		if ( $iPos === false )
			return $sPath;
			
		return substr( $sPath, $iPos + 1 );
	}
	
	//----------------------------------------------------------------------------------
	static public function getParentDir( $sPath )
	{
		$iPos = strrpos( $sPath, '/' );
		if ( $iPos === false )
			$iPos = strrpos( $sPath, '\\' );
		
		if ( $iPos === false )
			return '.';
			
		return substr( $sPath, 0, $iPos/*length*/ );
	}
	
	//----------------------------------------------------------------------------------
	static public function getRootDir( $sPath )
	{
		$iPos = strpos( $sPath, '/' );
		if ( $iPos === false )
			$iPos = strpos( $sPath, '\\' );
		
		if ( $iPos === false )
			return $sPath;
			
		return substr( $sPath, 0, $iPos );
	}
  
	//----------------------------------------------------------------------------------
  static public function removeContentFileOrDir( $oResponse, $sPath )
  {
    if ( file_exists( $sPath ) )
    {
      if ( !is_writable( $sPath ) )
      {
        $oResponse->error( 'Cannot remove the file (file not writable) : '.$sPath );
        return;
      }
      if ( is_file( $sPath ) )
      {
        if ( !unlink( $sPath ) )
        {
          $oResponse->error( 'Removing file failed : '.$sPath );
          return;
        }
      }
      else
      {
        if ( !rmdir( $sPath ) )
        {
          $oResponse->error( 'Removing directory failed : '.$sPath );
          return;
        }
      }
    }
    
    $oResponse->requestExecuted();
  }
	
	//----------------------------------------------------------------------------------
	static public function renameContentFileOrDir( $oResponse, $sPath, $sNewName )
	{
		if ( !file_exists( $sPath ) )
  	{
  		$oResponse->error( 'Path does not exist : '.$sPath );
  		return;
  	}
  	if ( !is_writable( $sPath ) )
  	{
  		$oResponse->error( 'Path is not writable : '.$sPath );
  		return;
  	}
  	
  	$sParentDir = FileManager::getParentDir( $sPath );  	
  	
  	$sNewPath = $sParentDir.'/'.$sNewName;
  	
  	if ( file_exists( $sNewPath ) )
  	{
  		$oResponse->error( 'A file already exists with this name : '.$sNewPath );
  		return;
  	}
  	
  	$bRes = rename( $sPath, $sNewPath );
  	
  	if ( !$bRes )
  	{
  		$oResponse->error( 'Cannot rename the path : '.$sPath );
  		return;
  	}
  	
		$oResponse->requestExecuted();
	}
  
	//----------------------------------------------------------------------------------
  static public function uploadContentFile( $oResponse, $sName, $sTmpName, $sDirPath )
  {
    move_uploaded_file( $sTmpName, $sDirPath.$sName );
    $oResponse->requestExecuted();
  }
}

?>